-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ziga/add personal sign authentication message #1811
Conversation
7c02e15
to
1976388
Compare
47cbbb3
to
2c1f41c
Compare
f148e94
to
c2f85ed
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks Ziga. Much better now.
A few improvements and this should be good to merge
go/common/viewingkey/viewing_key.go
Outdated
var PersonalSignMessageSupportedVersions = []int{1} | ||
|
||
// SignatureType is used to differentiate between different signature types (string is used, because int is not RLP-serializable) | ||
type SignatureType string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can make SignatureType
an iota to avoid the conversions and minimize the data
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was my initial approach, but having SignatureType
of type int
causes problems with RLP serialisation.
And errors like this:
Cause: rlp: type int is not RLP-serializable (struct field viewingkey.RPCSignedViewingKey.SignatureType) (struct field common.LogSubscription.ViewingKey)"}} component=test_log
I can change it to []byte to save some space. What do you think? Do you have some other ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about int8 or one of the other int types?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all int types fail with the same error unfortunately
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about uints?
go/common/viewingkey/viewing_key.go
Outdated
@@ -245,8 +274,8 @@ func CheckSignatureAndReturnAccountAddress(hashBytes []byte, signature []byte) ( | |||
return nil, fmt.Errorf("invalid signature") | |||
} | |||
|
|||
// CheckEIP712Signature checks if signature is valid for provided userID and chainID and return address or nil if not valid | |||
func CheckEIP712Signature(userID string, signature []byte, chainID int64) (*gethcommon.Address, error) { | |||
// checkEIP712Signature checks if signature is valid for provided userID and chainID and return address or nil if not valid |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would be nice if these functions each lived in their own type behind an interface
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
go/common/viewingkey/viewing_key.go
Outdated
func CheckSignature(encryptionToken string, signature []byte, chainID int64, signatureType SignatureType) (*gethcommon.Address, error) { | ||
if signatureType == PersonalSign { | ||
return checkPersonalSignSignature(encryptionToken, signature, chainID) | ||
} else if signatureType == EIP712Signature { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if these checks were each in their type, then you can have a map of registered signature handlers, and make this method much simpler
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
func (o *TGLib) RegisterAccountPersonalSign(pk *ecdsa.PrivateKey, addr gethcommon.Address) error { | ||
// create the registration message | ||
personalSignMessage := viewingkey.GeneratePersonalSignMessage(string(o.userID), integration.TenChainID, 1) | ||
prefixedMessage := fmt.Sprintf(viewingkey.PersonalSignMessagePrefix, len(personalSignMessage), personalSignMessage) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this prefix logic be in the GeneratePersonalSignMessage
function as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Actually this prefixing can be removed by using accounts.TextHash
from geth, which adds the prefix and hashes the message + keeping it without a prefix is better for the new endpoints (wallets like Metamask automatically adds this prefix to the message)
General comment / question. Is it critical if our system is vulnerable to the following (possible attack)? When users sign the message to authenticate them they have 3 options (legacy will be removed and I won't talk about it). |
If I understand the attack correctly, the user wants to read the data of an account they don't control. For this, they have to produce a signed message of one of the 2 formats that contains the target address in the right place and sign that with a key they control that somehow, when going through our recovery algorithm will produce the right values? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks Ziga. I think it looks good now. The responsibilities are quite clear.
One last thing to check if other int data types work for the type .
go/common/viewingkey/viewing_key.go
Outdated
var PersonalSignMessageSupportedVersions = []int{1} | ||
|
||
// SignatureType is used to differentiate between different signature types (string is used, because int is not RLP-serializable) | ||
type SignatureType string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about int8 or one of the other int types?
go/common/viewingkey/viewing_key.go
Outdated
SignatureType SignatureType | ||
} | ||
|
||
// SignatureChecker is an interface for checking if signature is valid for provided encryptionToken and chainID and return address or nil if not valid |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return "signing address"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Why this change is needed
We want to use Rainbowkit (https://www.rainbowkit.com/) in the future and they don't support EIP-712 messages yet.
To use them we need to add personal sign message, because it is impossible to overwrite signer there.
In order to avoid confusion I also refactored and simplified parts of code for signature verification and introduced signatureType.
What changes were made as part of this PR
PR checks pre-merging
Please indicate below by ticking the checkbox that you have read and performed the required
PR checks